package com.yds.modewithprinceple.prototype;

import android.util.Log;

import androidx.annotation.NonNull;

import java.util.ArrayList;

/**
 * @author YDS
 * @date 2021/5/7
 * @discribe 原形模式举例
 * <p>
 * 1、Person类继承implements Cloneable接口，Cloneable标示接口，表示这个对象可以被拷贝。
 * 2、clone方法是Object中的方法，如果实现clone方法没有继承Cloneable会抛出异常
 */
@SuppressWarnings("all")
public class Person implements Cloneable {
    private String name;
    private int age;
    private ArrayList<String> books = new ArrayList<>();

    public Person() {
        Log.i("Simon", "Person构造方法");
    }

    @NonNull
    @Override
    public Object clone() {
        Person person = null;
        try {
            person = (Person) super.clone();
            person.age = this.age;
            person.name = this.name;
            /**
             * age和name为啥不会影响，而只有books是浅拷贝呢?
             * 因为int和String一个是整形一个是字符串，都是值类型而不是引用类型，因此他们不需要clone，在副本对象克隆好之后，直接返回给客户端对象即可
             * 数值拷贝没有深浅拷贝之分，注意引用变量拷贝，如果没有再次加clone方法，默认是浅拷贝。浅拷贝：获得变量本身，深拷贝：获得一个新的一模一样的变量。
             */
            person.books = (ArrayList<String>) this.books.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        return person;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public ArrayList<String> getBooks() {
        return books;
    }

    public void addBook(String bookName) {
        books.add(bookName);
    }

    public void setBooks(ArrayList<String> books) {
        this.books = books;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", books=" + books +
                '}';
    }
}
